package secret

import (
	"encoding/base64"
	"fmt"
	"strings"
	"time"

	"gitee.com/go-course/go9/projects/devcloud/cmdb/conf"
	"github.com/go-playground/validator/v10"
	"github.com/infraboard/mcube/crypto/cbc"
	"github.com/rs/xid"
)

var (
	validate = validator.New()
)

func NewSecretSet() *SecretSet {
	return &SecretSet{
		Items: []*Secret{},
	}
}

func (s *SecretSet) Add(item *Secret) {
	s.Items = append(s.Items, item)
}

func NewCreateSecretRequest() *CreateSecretRequest {
	return &CreateSecretRequest{
		Enabled: true,
	}
}

func (req *CreateSecretRequest) TableName() string {
	return "secrets"
}

func New(req *CreateSecretRequest) *Secret {
	return &Secret{
		Meta: NewMeta(),
		Spec: req,
	}
}

func (req *CreateSecretRequest) Validate() error {
	return validate.Struct(req)
}

func NewMeta() *Meta {
	return &Meta{
		Id:       xid.New().String(),
		CreateAt: time.Now().Unix(),
	}
}

func (i *CreateSecretRequest) Desense() {
	i.ApiSecret = "****"
}

// 加密
func (i *Secret) EncryptAPISecret(key string) error {
	s := i.Spec
	// 判断文本是否已经加密 @ciphered@xxxx
	if strings.HasPrefix(s.ApiSecret, conf.CIPHER_TEXT_PREFIX) {
		return fmt.Errorf("text has ciphered")
	}

	// 加密后是密文, 密文不等你字符串, 他就是一个二进制数据
	cipherText, err := cbc.Encrypt([]byte(s.ApiSecret), []byte(key))
	if err != nil {
		return err
	}

	base64Str := base64.StdEncoding.EncodeToString(cipherText)
	s.ApiSecret = fmt.Sprintf("%s%s", conf.CIPHER_TEXT_PREFIX, base64Str)
	return nil
}

// 解密
func (i *Secret) DecryptAPISecret(key string) error {
	s := i.Spec
	// 判断文本是否已经是明文
	if !strings.HasPrefix(s.ApiSecret, conf.CIPHER_TEXT_PREFIX) {
		return fmt.Errorf("text is plan text")
	}

	base64CipherText := strings.TrimPrefix(s.ApiSecret, conf.CIPHER_TEXT_PREFIX)

	cipherText, err := base64.StdEncoding.DecodeString(base64CipherText)
	if err != nil {
		return err
	}

	planText, err := cbc.Decrypt([]byte(cipherText), []byte(key))
	if err != nil {
		return err
	}

	s.ApiSecret = string(planText)
	return nil
}
